#include "kdcsubtitlemodel.h"

#include <KLocale>
#include <kdcnamespace.h>
#include <kdclib.h>
#include <kdcsubtitle.h>
#include <subtitle.h>
#include <QMimeData>

KDCSubtitleModel::KDCSubtitleModel( QObject *aParent ) : QAbstractTableModel( aParent )
{

}

KDCSubtitleModel::~KDCSubtitleModel()
{

}

int KDCSubtitleModel::rowCount( const QModelIndex &aParent ) const
{
	if ( !pMovies.isEmpty() )
	{
		int res = 0;
		foreach( KDCMovie *mov, pMovies )
			res += ( 1 + mov->subtitles()->subtitles().size() );
		return res;
	}
	return 0;
}

QVariant KDCSubtitleModel::data( const QModelIndex &aIndex, int aRole ) const
{
	int aMovieIdx = movieFromRow( aIndex.row() );
	int tRow = movieTitleRow( aMovieIdx );
	KDCMovie *movie = pMovies.at( aMovieIdx );
	if ( aRole == Qt::EditRole || aRole == Qt::DisplayRole )
	{
		if ( aRole == Qt::EditRole && aIndex.row() == tRow )
			return QVariant();
		if ( aRole == Qt::DisplayRole && aIndex.row() == tRow )
			return fileName( movie->metaData()->name() );

		QVariant tmp;
		switch ( aIndex.column() )
		{
			case 0: return fileName( movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->fileName() );
			case 1: return movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->codec();
			case 2: return movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->fps();
			case 3: return movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->delay();
		}
	}
	if ( aRole == MovieTitleRowRole )
		return tRow;
	return QVariant();
}

bool KDCSubtitleModel::setData( const QModelIndex &aIndex, const QVariant &aValue, int aRole )
{
	int aMovieIdx = movieFromRow( aIndex.row() );
	int tRow = movieTitleRow( aMovieIdx );
	KDCMovie *movie = pMovies.at( aMovieIdx );

	if ( aRole == Qt::EditRole )
	{
		if ( aIndex.row() == tRow )
			return false;
		switch ( aIndex.column() )
		{
			case 1: movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->setCodec( aValue.toString() ); break;
			case 2: movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->setFps( aValue.toDouble() ); break;
			case 3: movie->subtitles()->subtitles().at( aIndex.row() - tRow - 1 )->setDelay( aValue.toInt() ); break;
		}
		emit dataChanged( aIndex, aIndex );
		return true;
	}
	return false;
}

QModelIndex KDCSubtitleModel::parent( const QModelIndex &aIndex ) const
{
	return QModelIndex();
}

int KDCSubtitleModel::columnCount( const QModelIndex &aParent ) const
{
	return 4;
}

Qt::ItemFlags KDCSubtitleModel::flags(const QModelIndex &aIndex ) const
{
	Qt::ItemFlags res = Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
	int aMovieIdx = movieFromRow( aIndex.row() );
	int tRow = movieTitleRow( aMovieIdx );

	if ( aIndex.row() != tRow )
		res |= Qt::ItemIsSelectable;
	if ( aIndex.column() > 0 && aIndex.row() != tRow )
		res |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled; 
    return res;
}

QVariant KDCSubtitleModel::headerData( int aSection, Qt::Orientation aOrientation, int aRole ) const
{
	if ( aRole == Qt::DisplayRole && aOrientation == Qt::Horizontal )
	{
		switch ( aSection )
		{
			case 0: return i18n("File name");
			case 1: return i18n("Codec");
			case 2: return i18n("Fps");
			case 3: return i18n("Delay");
		}
	}
	return QAbstractTableModel::headerData( aSection, aOrientation, aRole );
}

void KDCSubtitleModel::setMovie( KDCMovie *aMovie )
{
	pMovies.clear();
	if ( aMovie )
	{
		pMovies.append( aMovie );
		pMovies.append( aMovie->subMovies() );
	}
	reset();
}

int KDCSubtitleModel::movieFromRow( int aRow ) const
{
	int rows = 0;
	for( int i=0; i<pMovies.size(); ++i )
	{
		rows += ( 1 + pMovies.at( i )->subtitles()->subtitles().size() );
		if ( aRow <= rows - 1 )
			return i;
	}
	return 0;
}

int KDCSubtitleModel::movieTitleRow( int aMovieIdx ) const
{
	int rows = 0;
	for( int i=0; i<pMovies.size(); ++i )
	{
		if ( i == aMovieIdx )
			return rows;
		rows += ( 1 + pMovies.at( i )->subtitles()->subtitles().size() );
	}
	return 0;
}

QList<int> KDCSubtitleModel::movieSubtitleRows( int aMovieIdx ) const
{
	QList<int> list;
	KDCMovie *movie = pMovies.at( aMovieIdx );
	int tRow = movieTitleRow( aMovieIdx );
	for( int i=0; i<movie->subtitles()->subtitles().size(); ++i )
		list.append( tRow + i + 1 );
	return list;
}

void KDCSubtitleModel::removeSubtitle( int aRow )
{
	emit beginTitleRowsChanged();
	int idx = movieFromRow( aRow );
	KDCMovie *movie = pMovies.at( idx );
	idx = movieSubtitleRows( idx ).indexOf( aRow );
	Subtitle *sub = movie->subtitles()->subtitles().at( idx );
	beginRemoveRows( QModelIndex(), aRow, aRow );
	movie->subtitles()->remove( idx );
	delete sub;
	endRemoveRows();
	emit endTitleRowsChanged();
}

void KDCSubtitleModel::addSubtitle( KDCMovie *aMovie, Subtitle *aSubtitle )
{
	emit beginTitleRowsChanged();
	int idx = movieSubtitleRows( pMovies.indexOf( aMovie ) ).last();
	beginInsertRows( QModelIndex(), idx + 1, idx + 1 );
	aMovie->subtitles()->add( aSubtitle );
	endInsertRows();
	emit endTitleRowsChanged();
}

QStringList KDCSubtitleModel::mimeTypes() const
{
	return QStringList() << "application/vnd.text.list";
}

Qt::DropActions KDCSubtitleModel::supportedDropActions() const
{
	return Qt::CopyAction;
}

QMimeData* KDCSubtitleModel::mimeData( const QModelIndexList &aIndexes ) const
{
	QMimeData *res  = new QMimeData;
	res->setData( mimeTypes().first(), QByteArray::number( aIndexes.first().row() ) );
	return res;
}

bool KDCSubtitleModel::dropMimeData( const QMimeData *aData, Qt::DropAction aAction, int aRow, int aColumn, const QModelIndex &aParent )
{
	if ( aAction == Qt::IgnoreAction)
		return true;

	if ( !aData->hasFormat( mimeTypes().first() ) )
		return false;
		
	int row = aData->data( mimeTypes().first() ).toInt();
	
	int idx = movieFromRow( row );
	if ( aParent.isValid() )
		aRow = aParent.row();
	else
		aRow = rowCount() - 1;
	if ( idx != movieFromRow( aRow ) )
		return false;
	QList<int> list = movieSubtitleRows( idx );
	KDCMovie *movie = pMovies.at( idx );
	if ( aRow == movieTitleRow( idx ) )
		++aRow;
	movie->subtitles()->move( list.indexOf( row ), list.indexOf( aRow ) );
	return true;
}

QList<int> KDCSubtitleModel::titleRows() const
{
	QList<int> res;
	for ( int i=0; i<pMovies.size(); ++i )
		res.append( movieTitleRow( i ) );
	return res;
}
